package thread;
//构造一个阻塞队列
public class testDemo22 {
    public static void main(String[] args) {
        Myblockingqueue queue=new Myblockingqueue(100);
        /*queue.put(1);
        queue.put(2);
        queue.put(3);
        System.out.println(queue.take());
        System.out.println(queue.take());
        System.out.println(queue.take());*/
        //进行两个线程的测试
        Thread t1=new Thread(()->{
            int n=1;
            while (true){
                try {
                    queue.put(n);
                    System.out.println("生产的元素"+n);
                    n++;//当太多了就进入阻塞
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

            }
        });
        Thread t2=new Thread(()->{
            while (true){
                try {

                    int n=queue.take();
                    System.out.println("消费的元素"+n);

                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t1.start();
        t2.start();
    }
}
class Myblockingqueue{
    //声明一个环形数组
    private int[] elems=null;
    private int head=0;
    private int tail=0;
    private int size=0;
    private Object lock=new Object();
    //在实例化时，初始化这个数组
    public Myblockingqueue(int capcity){
        elems=new int[capcity];
    }
    public void put(int elem) throws InterruptedException {
        //防止多线程状态下，发生线程安全问题
        synchronized (lock){
            //判断条件，是否满了，满了就进入阻塞
            while (size==elems.length){
                lock.wait();
            }
            elems[tail]=elem;
            size++;
            tail++;
            if (tail>elems.length-1){
                tail=0;
            }
            //唤醒取出线程
            lock.notify();
        }
    }
    public int take() throws InterruptedException {
        int elem=0;
        //判断条件，如果为空，那么就进入阻塞
        synchronized (lock){
            while (size==0){
                //进入线程等待
                lock.wait();
            }
            elem=elems[head];
            head++;
            size--;
            if (head>elems.length-1){
                head=0;
            }
            lock.notify();
            return elem;
        }
    }
}
